import { mergeOptions } from "./../utils/index";

//创建vue全局方法
export function initGlobApi(Vue) {
  // 源码
  // Vue.options = {created: [a,b,c],watch:[a,b]}
  Vue.options = {};
  Vue.Mixin = function (mixin) {
    // mixin ==> {}
    // 对象的合并---就是对多个多次调用Vue.Mixin进行拼接合并对象--通过代码实现成--{created: [a,b,c],watch:[a,b]}--这种格式
    Vue.options = mergeOptions(this.options, mixin); // this是vue实例vm 访问options由于原型链可以访问到 Vue.options
    console.log(Vue.options, "Vue.optionsVue.options99999");
  };

  //2.  实现vue组件
  // 2.1 创建vue全局方法，声明一个全局属性里面放全局组件，以及创建一个可以创建全局组件的方法
  Vue.options.components = {}; //存放全局组件
  Vue.component = function (id, componentDef) {
    // 如果 componentDef 是一个函数，说明用户自己调用了 Vue.extend
    // 不是函数(局部组件--内部) 就用 extend函数包装一下
    componentDef.name = componentDef.name || id;
    componentDef = this.extend(componentDef); //this就是Vue 因为是Vue.component调用的。this.extend()会返回一个构造函数，或者叫类
    // 2.2 组件实现的核心是 调用Vue.extend()这个方法
    this.options.components[id] = componentDef;
    console.log(this.options, "组件化--components--this.options.components");
  };

  // 2.3 Vue.extend方法 声明 核心    创建 子类
  Vue.extend = function (options) {
    const spuer = this
    const Sub = function vuecomponent(opts) {
      // 钩 子函数 用户自己的options配置项 ===> 局部组件的
      // ===> 使用 new Sub().$mount()
      console.log(
        opts,
        "opts",
        options,
        "options",
        this,
        "this",
        "组件化---vuecomponent",
      );
      //初始化 this指向注意一下--这里的this是当 new Sub()的时候 也就是局部组件的this
      this._init(opts);
    };
    // 子组件继承父组件中属性 Vue 构造函数 实现类的继承
    Sub.prototype = Object.create(spuer.prototype);
    // 问题 子组件中this指向问题
    //
    Sub.prototype.constructor = Sub;
    // 将父组件中的属性合并到子组件中
    Sub.options = mergeOptions(spuer.options, options);

    return Sub;
  };
}
